package com.liangtian.mdm.dm.jsp.service.imp;

import com.liangtian.mdm.base.filter.CameHumpInterceptor;
import com.liangtian.mdm.base.utils.PlatForm;
import com.liangtian.mdm.dm.checkRule.dao.CheckRuleDao;
import com.liangtian.mdm.dm.checkRule.model.CheckRule;
import com.liangtian.mdm.dm.common.constant.TableConst;
import com.liangtian.mdm.dm.common.constant.UrlConst;
import org.apache.commons.lang3.StringUtils;
import com.liangtian.mdm.dm.config.model.AttrConfig;
import com.liangtian.mdm.dm.group.dao.AttrGroupDao;
import com.liangtian.mdm.dm.group.dao.DataViewFlowDao;
import com.liangtian.mdm.dm.group.model.AttrGroup;
import com.liangtian.mdm.dm.jsp.common.*;
import com.liangtian.mdm.dm.jsp.dao.GenJspDao;
import com.liangtian.mdm.dm.jsp.model.GenSelect;
import com.liangtian.mdm.dm.jsp.model.GenSelectType;
import com.liangtian.mdm.dm.jsp.service.GenJspService;
import com.liangtian.mdm.dm.listener.CacheUtil;
import com.liangtian.mdm.dm.model.dao.ModelDao;
import com.liangtian.mdm.dm.model.model.Model;
import com.liangtian.mdm.system.business.dao.SysBusinessDao;
import com.liangtian.mdm.system.business.model.SysBusiness;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings({"unchecked", "rawtypes"})
@Service
public class GenJspServiceImpl implements GenJspService {

    @Autowired
    private ModelDao modelDao;
    @Autowired
    private AttrGroupDao attrGroupDao;
    @Autowired
    private GenJspDao genJspDao;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    CheckRuleDao checkRuleDao;
    @Autowired
    SysBusinessDao sysBusinessDao;
    @Autowired
    DataViewFlowDao viewDao;

    /**
     * todo: 将jsp模板根据模型类型创建相应的文件目录和复制对应的jsp文件模板
     */
    @Override
    public void createJsp(String modelId) {

        // 本模型--当前操作的模型
        Model model = cacheUtil.getModel(modelId); // 缓存中获取具体模型对象
        // 数据类型【0-列表、1-父子树、2-分类树】
        String classType = model.getClassType();
        // 模型是否有从表
        Map<String, Object> isHasSubMap = isHasSub(modelId);

        if ("false".equals(isHasSubMap.get("isReady"))) {
            throw new RuntimeException("该模型存在从表没有建立实体，暂不能生成页面！");
        }
        if (1 == model.getIsJspCreate()) {// 已经创建了页面
            //这个删除的是am文件夹下面的的已经存在文件夹
            JspUtil.clearFiles(model.getTableName()); // 删除这个目录下的文件及文件夹
        }
        if ("0".equals(classType)) { // 列表
            if (model.getIsMoreView() == 1) {// 多视图列表
                JspUtil.copyTempViewFile(model);// 根据模型复制模板文件到直接路径下
                this.createListViewJsp(model, isHasSubMap);
            } else {// 普通列表
                JspUtil.copyTempFile(model);// 根据模型复制模板文件到直接路径下
                this.createListJsp(model, isHasSubMap);
            }
        } else { //树-（父子树和分类树）
            if (model.getIsMoreView() == 1) {// 如果是多视图树
                JspUtil.copyTreeTabViewFile(model);// 根据模型复制模板文件到直接路径下
                this.createTreeViewJsp(model, isHasSubMap);
            } else {// 是树模型，但不是多视图
                JspUtil.copyTreeTabFile(model);// 根据模型复制模板文件到直接路径下
                this.createTreeJsp(model, isHasSubMap);
            }
        }
        // 生成（树，弹出框需要特殊弹出框的页面）
        // **model --本模型 ，configLst-属性列，result_map--是否主从关系
        createOther(model, isHasSubMap);
    }

    /**
     * todo:创建本模型中，特殊属性类型的操作==1.弹出框 2.列表树 3.从表
     */
    private void createOther(Model model, Map<String, Object> isHasSubMap) {
        this.columnPop(model); // 生成这个模型下面的弹出框页面 每个列类型为popList的产生一个弹出框页面
        this.columTree(model); // 生成这个模型下面的弹出框页面 每个列类型为treeList的产生一个弹出框页面
        // 模型为主表，还需生成从表页面
        model.setIsJspCreate(1);
        modelDao.updateModelFlag(model);
        if (!"1".equals(String.valueOf(model.getIsSubtable()))) {
            // 模型为主表，还需生成从表页面
            if ((boolean) isHasSubMap.get("flag")) {
                List<Model> subModels = (List<Model>) isHasSubMap.get("subModel");
                for (Model sub : subModels) {
                    createJsp(sub.getId());
                }
            }
        }
    }

    /**
     * 查询对应页面需要显示的字段 如1代表查询页面，则查询出查询页面需要显示的字段
     *
     * @param pageType
     * @param modelId
     * @return
     */
    private Map<String, Object> getEditJspAttr(String pageType, String modelId, List<AttrConfig> configLst) {
        Map<String, Object> resMap = new HashMap<>();
        Map<String, Map<String, AttrConfig>> map = new HashMap<String, Map<String, AttrConfig>>();
        boolean flag = false;

        List<AttrConfig> jspAttrLst = new ArrayList<AttrConfig>(); // 过滤后对应页面显示的属性
        List<AttrConfig> RadioList = new ArrayList<AttrConfig>();
        List<AttrConfig> CheckboxList = new ArrayList<AttrConfig>();
        List<AttrConfig> selectList = new ArrayList<AttrConfig>();
        List<AttrConfig> selectCascadList = new ArrayList<AttrConfig>();
        List<AttrConfig> fileLst = new ArrayList<AttrConfig>();
        for (AttrConfig attrConfig : configLst) { // 循环查找出页面显示的字段
            if (attrConfig.getShowPage().contains(pageType)) { // 在对应的页面显示
                jspAttrLst.add(attrConfig);
            }
        }
        for (AttrConfig attrConfig : jspAttrLst) { // 循环查找出页面显示的字段
            // 单选框
            if (attrConfig.getAttrType() != null && "radioType".equals(attrConfig.getAttrType())) {
                flag = true;
                AttrConfig attrConfigRadio = cacheUtil.getAttrMap(modelId).get(attrConfig.getAttrColumn());
                RadioList.add(attrConfigRadio);
            } else if (attrConfig.getAttrType() != null && "checkBoxType".equals(attrConfig.getAttrType())) {// 复选框
                flag = true;
                AttrConfig attrConfigCheckbox = cacheUtil.getAttrMap(modelId).get(attrConfig.getAttrColumn());
                CheckboxList.add(attrConfigCheckbox);
            } else if (attrConfig.getAttrType() != null && "selectList".equals(attrConfig.getAttrType())) {// 如果是下拉框
                // 只需要加载，下拉框是级联的下拉框
                if ("2".equals(attrConfig.getModuleType())) {// 级联数据
                    AttrConfig attr = cacheUtil.getAttrMap(modelId).get(attrConfig.getAttrColumn());
                    selectList.add(attr);// 所有级联下拉框

                    Map<String, AttrConfig> valMap = new HashMap<String, AttrConfig>();
                    valMap.put("current", attrConfig);
                    String key = attrConfig.getCascadedAttr();// 获取级联的级联列值
                    if (null != key && !"".equals(key)) {
                        // 当前属性的级联对象
                        AttrConfig preAttr = cacheUtil.getAttrConfig(modelId, key);
                        // if("selectList".equals(preAttr.getAttrType())){
                        selectCascadList.add(preAttr);// 所有下拉框的级联对象集合
                        // }
                        valMap.put("prefix", preAttr);
                    } else {
                        valMap.put("prefix", null);
                    }
                    // 级联当前属性的对象
                    AttrConfig sufixAttr = cacheUtil.getCascadeAttrConfig(modelId, attrConfig.getAttrId());
                    if (sufixAttr != null)
                        valMap.put("sufix", sufixAttr);
                    else
                        valMap.put("sufix", null);
                    map.put(attrConfig.getAttrColumn(), valMap);
                }
            } else if (attrConfig.getAttrType() != null && "BLOB".equals(attrConfig.getAttrType())) {
                fileLst.add(attrConfig);
            }
        }
        resMap.put("selectMap", map);
        resMap.put("flag", flag);
        resMap.put("jspAttrLst", jspAttrLst);
        resMap.put("selectList", selectList);
        resMap.put("selectCascadList", selectCascadList);
        resMap.put("attributeRadioList", RadioList);
        resMap.put("attributeCheckboxList", CheckboxList);
        resMap.put("fileLst", fileLst);
        return resMap;
    }

    private List<AttrConfig> getJspAttr(String pageType, Model model) {
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId()); // 查询没有被删除的属性信息及配置信息
        List<AttrConfig> jspAttrLst = new ArrayList<AttrConfig>(); // 过滤后对应页面显示的属性
        //这块针对是否多视图做了以下更改，如果属性设置那块，设置页面不显示的话，
        //那么列表和新增及相关编辑页面还是不允许看到不显示的字段
        for (AttrConfig attrConfig : configLst) { // 循环查找出页面显示的字段
            if (attrConfig.getShowPage().contains(pageType)) { // 在对应的页面显示
                jspAttrLst.add(attrConfig);
            }
        }
        return jspAttrLst;
    }

    /**
     * 查询有属性组的属性
     */
    private List<AttrConfig> getAddJspAttrMap(String modelId, String groupId, String pageType) {
        List<AttrConfig> attrConfigLst = cacheUtil.getAttrListByGroup(modelId, groupId);
        //生成页面这块查询属性的话，应该将设置不显示的子段过滤掉

        List<AttrConfig> jspAttrLst = new ArrayList<AttrConfig>();
        for (AttrConfig attrConfig : attrConfigLst) {
            if (attrConfig.getShowPage().contains(pageType)) { // 在对应的页面显示
                jspAttrLst.add(attrConfig);
            }
        }
        return jspAttrLst;

    }

    /**
     * 根据页面显示的字段拼写html字符串
     */
    private String spellJspStr(String pageType, Model model) {
        String str = null;
        List<AttrConfig> jspAttrLst = this.getJspAttr(pageType, model); // 查询这个页面显示的属性
        if ("1".equals(pageType)) { // 拼写查询页面、维护页面
            str = ListJspCreate.spellSearchJsp(jspAttrLst, model); // 拼写查询页面
        } else if ("2".equals(pageType)) { // 拼写申请新增和申请编辑
            str = ListJspCreate.spellAddOrEditJsp(jspAttrLst, model); // 拼写申请页面
        } else if ("pop".equals(pageType)) { // 拼写弹出框列表页面
            str = ListJspCreate.spellPopJsp(jspAttrLst, model); // 拼写申请页面
        } else if ("4".equals(pageType)) { // 拼写详情页面
            str = ListJspCreate.spellAddOrEditJsp(jspAttrLst, model); // 拼写申请页面
        } else if ("3".equals(pageType)) {// 拼写变更编辑
            str = ListJspCreate.spellSearchJsp(jspAttrLst, model); // 拼写变更页面
        }
        return str;
    }

    /**
     * 根据查询页面的，变更查询---变更历史，展示数据
     */
    private String spellupdateHisJspStr(String pageType, Model model) {
        String str = null;
        List<AttrConfig> jspAttrLst = this.getJspAttr(pageType, model); // 查询这个页面显示的属性
        if ("1".equals(pageType)) { // 拼写查询页面、维护页面
            str = ListJspCreate.spellPopJsp(jspAttrLst, model); // 拼写查询页面
        }
        return str;
    }

    private String spellJspStrDetail(String pageType, Model model) {
        String str = null;
        List<AttrConfig> jspAttrLst = this.getJspAttr(pageType, model); // 查询这个页面显示的属性
        if ("4".equals(pageType)) { // 拼写申请页面
            str = ListJspCreate.spellApplyJspDetail(jspAttrLst, model); // 拼写申请页面
        }
        return str;
    }

    /**
     * *
     * <p>
     * Title: 动态拼写（新增、编辑、变更编辑）页面 form下面的动态div
     * </p>
     *
     * @author : xiaoliu
     * @date :2016年7月25日下午7:52:26
     */
    private String spellJspAddStr(String pageType, Model model, String opaType, List<AttrGroup> groupLst,
                                  List<AttrConfig> configLstCom) {
        StringBuilder sb = new StringBuilder();// 将读取出来的数据，动态拼接成字符串
        List<GenSelectType> typeList = (List<GenSelectType>) this.getSelected(model, opaType).get("selLst");
        List<String> columList = (List<String>) this.getSelected(model, opaType).get("columList");
        if (groupLst.size() > 0) {
            if (pageType.equals("3")) {// 变更编辑
                for (int i = 0; i < groupLst.size(); i++) {
                    AttrGroup attrGroup = groupLst.get(i);
                    String groupID = attrGroup.getId();// 获取groupID
                    String groupName = attrGroup.getGroupName();// 获取属性组名称
                    sb.append("<shiro:hasPermission name='" + model.getTableName() + ":" + groupID + "'>" + "\r\n");
                    sb.append("<fieldset class='scheduler-border'>" + "\r\n");
                    sb.append("<legend class='scheduler-border'>" + groupName + "</legend>" + "\r\n");
                    List<AttrConfig> configLst = this.getAddJspAttrMap(model.getId(), groupID, pageType);
                    if (configLst.size() > 0) {// 属性组里有属性
                        for (int j = 0; j < configLst.size(); j++) {
                            AttrConfig attrConfig = configLst.get(j);
                            String ruleId = attrConfig.getRuleTypeId();
                            CheckRule checkRule = null;
                            if (ruleId != null) {
                                checkRule = checkRuleDao.getById(ruleId);
                            }
                            // 写了一个方法，返回拼接字符串
//							sb.append(AddJspCreate.searchReturnType(typeList, attrConfig, model, opaType, checkRule,
//									null));
                            sb.append(AddJspCreate.searchViewType(typeList, columList, attrConfig, model, opaType, checkRule,
                                    null));
                        }
                    }
                    sb.append(AddJspCreate.spellButtonReplace(model, opaType));
                    sb.append("</fieldset>" + "\r\n" + "\r\n");
                    sb.append("</shiro:hasPermission>" + "\r\n");
                }
            } else {
                if (model.getIsMoreView() == 1) {// 表示多视图模型
                    sb.append(" <div class='form-group draggable' >\r\n");
                    // sb.append(" <label class='col-sm-4 control-label'
                    // align='left'>模型视图列表</label>\r\n");
                    sb.append("    <label class='col-sm-4 control-label' align='left'>视图列表</label>\r\n");
                    sb.append("    <div class='col-sm-5' >    \r\n");
                    for (int i = 0; i < groupLst.size(); i++) {
                        AttrGroup attrGroup = groupLst.get(i);
                        String groupID = attrGroup.getId();// 获取groupID
                        String groupName = attrGroup.getGroupName();// 获取属性组名称
                        if (attrGroup.getIsDefaultView() == 1) {// 是默认视图---默认选中且不可编辑
                            sb.append("    <label class='checkbox-inline control-label'  >\r\n");
                            sb.append("       <input type='checkbox'  checked='checked'  disabled='disabled'   id='"
                                    + model.getTableName() + "_" + groupID + "'  >");
                            sb.append(groupName);
                            sb.append("    </label>        \r\n");
                        } else {// 不是默认视图
                            sb.append("    <label class='checkbox-inline control-label'  >\r\n");
                            sb.append("       <input type='checkbox'   id='" + model.getTableName() + "_" + groupID
                                    + "'  ng-click='check_" + model.getTableName() + "_" + groupID + "_Check()'>");
                            sb.append(groupName);
                            sb.append("    </label>        \r\n");
                        }
                    }
                    sb.append("  </div>\r\n");
                    sb.append("  </div>\r\n");
                }
                for (int i = 0; i < groupLst.size(); i++) {
                    AttrGroup attrGroup = groupLst.get(i);
                    String groupID = attrGroup.getId();// 获取groupID
                    String groupName = attrGroup.getGroupName();// 获取属性组名称
                    if (model.getIsMoreView() == 1) {// 表示多视图模型
                        sb.append("<fieldset class='scheduler-border' ng-show='" + model.getTableName() + "_" + groupID
                                + "'>" + "\r\n");
                        sb.append("<legend class='scheduler-border'>" + groupName + "</legend>" + "\r\n");
                        List<AttrConfig> configLst = this.getAddJspAttrMap(model.getId(), groupID, pageType);
                        if (configLst.size() > 0) {// 属性组里有属性
                            for (int j = 0; j < configLst.size(); j++) {
                                AttrConfig attrConfig = configLst.get(j);
                                String ruleId = attrConfig.getRuleTypeId();
                                CheckRule checkRule = null;
                                if (ruleId != null) {
                                    checkRule = checkRuleDao.getById(ruleId);
                                }
                                // 写了一个方法，返回拼接字符串
                                sb.append(AddJspCreate.searchViewType(typeList, columList, attrConfig, model, opaType, checkRule,
                                        attrGroup));
                            }
                        }
                    } else {
                        sb.append("<shiro:hasPermission name='" + model.getTableName() + ":" + groupID + "'>" + "\r\n");
                        sb.append("<fieldset class='scheduler-border'>" + "\r\n");
                        sb.append("<legend class='scheduler-border'>" + groupName + "</legend>" + "\r\n");
                        List<AttrConfig> configLst = this.getAddJspAttrMap(model.getId(), groupID, pageType);
                        if (configLst.size() > 0) {// 属性组里有属性
                            for (int j = 0; j < configLst.size(); j++) {
                                AttrConfig attrConfig = configLst.get(j);
                                String ruleId = attrConfig.getRuleTypeId();
                                CheckRule checkRule = null;
                                if (ruleId != null) {
                                    checkRule = checkRuleDao.getById(ruleId);
                                }
                                // 写了一个方法，返回拼接字符串
                                sb.append(AddJspCreate.searchViewType(typeList, columList, attrConfig, model, opaType, checkRule,
                                        null));
                            }
                        }
                    }
                    sb.append(AddJspCreate.spellButtonReplace(model, opaType));
                    sb.append("</fieldset>" + "\r\n" + "\r\n");
                    if (model.getIsMoreView() == 1) {// 表示多视图模型
                        sb.append("\r\n");
                    } else {
                        sb.append("</shiro:hasPermission>" + "\r\n");
                    }
                }
            }
        }

        // 基本视图
        List<AttrConfig> attrLst = this.getAddJspAttrMap(model.getId(), null, pageType);
        if (attrLst.size() > 0) {
            if (model.getIsMoreView() == 1) {// 表示多视图模型
                sb.append("<fieldset class='scheduler-border'>" + "\r\n");
                // sb.append("<legend
                // class='scheduler-border'>"+"默认属性组"+"</legend>"+"\r\n");
                sb.append("<legend class='scheduler-border'>" + "基本视图" + "</legend>" + "\r\n");
            } else {
                sb.append("<shiro:hasPermission name='" + model.getTableName() + ":0'>" + "\r\n");
                sb.append("<fieldset class='scheduler-border'>" + "\r\n");
                // sb.append("<legend
                // class='scheduler-border'>"+"默认属性组"+"</legend>"+"\r\n");
                sb.append("<legend class='scheduler-border'>" + "基本视图" + "</legend>" + "\r\n");
            }
            for (int j = 0; j < attrLst.size(); j++) {
                AttrConfig attrConfig = attrLst.get(j);
                String ruleId = attrConfig.getRuleTypeId();
                CheckRule checkRule = null;
                if (ruleId != null) {
                    checkRule = checkRuleDao.getById(ruleId);
                }
                sb.append(AddJspCreate.searchViewType(typeList, columList, attrConfig, model, opaType, checkRule, null));
            }
            sb.append(AddJspCreate.spellButtonReplace(model, opaType));
            sb.append("</fieldset>" + "\r\n" + "\r\n");
            if (model.getIsMoreView() == 1) {// 表示多视图模型
                sb.append("\r\n");
            } else {
                sb.append(" </shiro:hasPermission>" + "\r\n");
            }
        }
        return sb.toString();
    }

    /**
     * *
     * <p>
     * Title: 生成详细信息页面
     * </p>
     *
     * @author : xiaoliu
     * @date :2016年9月22日下午5:00:27
     */
    private String spellJspDetailStr(String pageType, Model model, String opaType, List<AttrGroup> groupLst,
                                     List<AttrConfig> configLstCom) {
        StringBuilder sb = new StringBuilder();// 将读取出来的数据，动态拼接成字符串
        Map map = new HashMap<>();
        map.put("modelId", model.getId());
        map.put("groupId", null);
        List<AttrConfig> attrLst = this.getAddJspAttrMap(model.getId(), null, pageType);
        if (groupLst.size() > 0) {
            for (int i = 0; i < groupLst.size(); i++) {
                AttrGroup attrGroup = groupLst.get(i);
                String groupID = attrGroup.getId();// 获取groupID
                String groupName = attrGroup.getGroupName();// 获取属性组名称
                sb.append(" <shiro:hasPermission name='" + model.getTableName() + ":" + groupID + "'>" + "\r\n");
                sb.append("<fieldset class='scheduler-border'>" + "\r\n");
                sb.append("<legend class='scheduler-border'>" + groupName + "</legend>" + "\r\n");
                List<AttrConfig> configLst = this.getAddJspAttrMap(model.getId(), groupID, pageType);
                if (configLst.size() > 0) {// 属性组里有属性
                    for (int j = 0; j < configLst.size(); j++) {
                        AttrConfig attrConfig = configLst.get(j);
                        // 写了一个方法，返回拼接字符串
                        sb.append(DetailJspCreate.searchReturnDetailPage(attrConfig, model, opaType));
                    }
                }
                sb.append("</fieldset>" + "\r\n" + "\r\n");
                sb.append(" </shiro:hasPermission>" + "\r\n");
            }
        }
        if (attrLst.size() > 0) {
            sb.append(" <shiro:hasPermission name='" + model.getTableName() + ":0'>" + "\r\n");
            sb.append("<fieldset class='scheduler-border'>" + "\r\n");
            sb.append("<legend class='scheduler-border'>" + "默认属性组" + "</legend>" + "\r\n");
            for (int j = 0; j < attrLst.size(); j++) {
                AttrConfig attrConfig = attrLst.get(j);
                sb.append(DetailJspCreate.searchReturnDetailPage(attrConfig, model, opaType));
            }
            sb.append("</fieldset>" + "\r\n" + "\r\n");
            sb.append(" </shiro:hasPermission>" + "\r\n");
        }
        return sb.toString();
    }

    /**
     * *
     * <p>
     * Title: 根据modelid 和 列名查询下拉框的值
     * </p>
     *
     * @author : xiaoliu
     * @date :2016年7月28日下午7:48:00
     */
    @Override
    public List<GenSelect> getSelectDataSource(Map<String, String> map) {
        List<GenSelect> resultLst = null;
        String caseColumn = "";
        AttrConfig attrConfig = cacheUtil.getAttrConfig(map.get("modelId"), map.get("attrColumn"));// 查询模型某一列的配置信息
        Model model = cacheUtil.getModel(attrConfig.getDataSourceTable());
        map.put("sourceTable", model.getTableName());// 值来源表
//		String idSub = "to_number(t.id) asc,";
        String showColumn = attrConfig.getDataSourceColumn();
        if ("2".equals(attrConfig.getModuleType())) {// 这一列是级联设置的,查询出级联的条件列
            caseColumn = cacheUtil.getAttrConfig(model.getId(), attrConfig.getCascadedForeignKey()).getAttrColumn();
            // if(showColumn.indexOf(caseColumn)==-1){
            // showColumn+=","+caseColumn;
            // }
        }
        map.put("caseColumn", "");
        map.put("sourceCol", showColumn.replace(",", "||'_'||"));// 值来源列
        // map.put("sourceCol", showColumn.replace(",", " "));//值来源列
        // if(null !=map.get("id") && !"".equals(map.get("id"))){
        // Map<String, String> selMap=new HashMap<String, String>();
        // selMap.put("caseColumn", "");
        // //此种情况，是页面生成下拉框加载一个值
        // Model model2=cacheUtil.getModel(map.get("modelId"));
        // if("edit".equals(map.get("searchType")) ||
        // "treeTabEdit".equals(map.get("searchType")))
        // selMap.put("sourceTable", model2.getTableName());
        // else if("updateEdit".equals(map.get("searchType")) ||
        // "treeTabUpdateEdit".equals(map.get("searchType")))
        // selMap.put("sourceTable", model2.getTableName()+"_update");
        // selMap.put("sourceCol", attrConfig.getAttrColumn().replace(",",
        // "||'_'||"));
        // selMap.put("Id", map.get("id"));
        // //取下拉框的值（为属性来源表的ID）
        // List<GenSelect> list = genJspDao.getColumById(selMap);
        // if(list.size()!=0){
        // map.put("Id", list.get(0).getName());
        // //用下拉框的值即属性来源表的ID查询此下拉框的属性来源列from属性来源表（下拉框的页面显示为属性来源列）
        // resultLst = genJspDao.getColumById(map);
        // }
        // }else
        String isCascad = map.get("isCascad");// 判断是不是级联的查询操作
        if (null != isCascad && !"".equals(isCascad)) {// 说明是级联查询操作
            if (null != map.get("columnValue") && !"".equals(map.get("columnValue"))) {
                // 此种情况是点击下拉框查询出所有来源表的所有值
                map.put("conditionCol", caseColumn);
                map.put("caseColumn", caseColumn);
                resultLst = genJspDao.getSelectListAttrData(map);
            } else {
                // 此种情况是点击除下拉框之外的类型的属性所有值（from属性来源表）
                // resultLst = genJspDao.getSelectAttrData(map);
                resultLst = genJspDao.getSelectListAttrData(map);
            }
        } else {
            if (null != map.get("columnValue") && !"".equals(map.get("columnValue"))) {
                // 此种情况是点击下拉框查询出所有来源表的所有值
                map.put("conditionCol", caseColumn);
                map.put("caseColumn", caseColumn);
                resultLst = genJspDao.getSelectListAttrData(map);
            } else {
                // 此种情况是点击除下拉框之外的类型的属性所有值（from属性来源表）
                resultLst = genJspDao.getSelectAttrData(map);
            }
        }

        return resultLst;
    }

    /**
     * 生成变更页面的弹出框页面
     *
     * @param modelId type='update' operType='bgPopList'//变更页面的弹出框
     */
    private void spellUpdatePopPage(Model model, String operType, String jspType) {
        if ("0".equals(model.getClassType()) && !StringUtils.isBlank(model.getMaintableId())) {

        } else {
            JspUtil.copyPopTempFile(model, "");
            String targetFilePath = JspUtil.getFilePath(model.getTableName(), "bgPopList", "jsp"); // 根据业务名称加操作类型获取jsp地址
            List<AttrConfig> configList = this.getJspAttr("4", model);
            String formatJspStr = ListJspCreate.spellPopJsp(configList, model) + ""; // 拼接弹出页面单元格字符串
            ListJspCreate.createPopListPage(formatJspStr, targetFilePath, model, null, null, "bgPopList");
            String targetFilePathJs = JspUtil.getFilePath(model.getTableName(), "bgPopList", "js"); // 拼接js页面内容
            ListJsCreate.createBgPopJs(targetFilePathJs, model, operType, jspType);
        }
    }

    private void spellSubAddPage(Model model, String addStr, String operType, String Update, List<AttrConfig> configLst,
                                 List<AttrGroup> groupLst) {
        JspUtil.copySubAddTempFile(model, "");
        String targetFilePath = JspUtil.getFilePath(model.getTableName(), "updateAdd", "jsp"); // 根据业务名称加操作类型获取jsp地址
        AddJspCreate.createAddPage(addStr, targetFilePath, model, "updateAdd", "update", null);
        Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
        Map<String, Object> res_Map = this.getSelected(model, "add");
        String targetFilePath_add = JspUtil.getFilePath(model.getTableName(), "updateAdd", "js"); // 拼接js页面内容
        String mainTableId = model.getMaintableId();
        Model mainModel = cacheUtil.getModel(mainTableId);
        AddJsCreate.createAddJs(res_Map, targetFilePath_add, model, resMap, "updateAdd", "update", null, mainModel,
                groupLst);
    }

    /**
     * 生成弹出框页面 modelId type='C_001' operType='popList'//模型下的弹出框列
     * 针对动态模型的弹出框
     */
    private void spellPopListPage(AttrConfig conf, List<AttrConfig> configLst) {
        try {
            Model model = cacheUtil.getModel(conf.getModelId()); // 根据模型id查询
            Model sourceModel = cacheUtil.getModel(conf.getDataSourceTable()); // 根据模型id查询
            JspUtil.copyPopTempFile(model, conf.getAttrColumn());// 根据模型复制模板文件到直接路径下

            Map<String, String> modelIdMap = new HashMap<String, String>();
            modelIdMap.put("modelId", model.getId());

            String targetFilePath = JspUtil.getFilePath(model.getTableName(), conf.getAttrColumn() + "popList", "jsp"); // 根据业务名称加操作类型获取jsp地址
            String formatJspStr = ListJspCreate.spellPopJsp(configLst, model).toString(); // 拼接弹出页面单元格字符串
            ListJspCreate.createPopListPage(formatJspStr, targetFilePath, model, sourceModel, conf.getAttrColumn(),
                    "popList");

            String targetFilePathJs = JspUtil.getFilePath(model.getTableName(), conf.getAttrColumn() + "popList", "js"); // 拼接js页面内容
            if ("2".equals(conf.getModuleType())) { // 是级联设置型的弹出框
                String caseCondition = casePopFilter(conf); // 级联查询的条件
                AttrConfig confAttr = cacheUtil.getCascadeAttrConfig(conf.getModelId(), conf.getAttrId());
//				String cascadeAttrStrClear ="";
//				       cascadeAttrStrClear = cascadeAttrStrClear+this.spellCascadeAttrStrClear(conf,cascadeAttrStrClear);
//				       System.out.println(cascadeAttrStrClear);
                ListJsCreate.createPopCaseJs(targetFilePathJs, sourceModel, getPopColumnsStr(configLst),
                        conf.getAttrColumn(), caseCondition, confAttr, "list");
            } else { // 不是级联设置型的弹出框（那就是关联设置）
                AttrConfig confAttr = cacheUtil.getCascadeAttrConfig(conf.getModelId(), conf.getAttrId());
//				String cascadeAttrStrClear = "";
//				       cascadeAttrStrClear = cascadeAttrStrClear+this.spellCascadeAttrStrClear(conf,cascadeAttrStrClear);
                ListJsCreate.createPopJs(targetFilePathJs, sourceModel, getPopColumnsStr(configLst),
                        conf.getAttrColumn(), confAttr, "list");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //生成pop弹出列表页面（针对非动态模型相关的表 例如==物料表，用户表）
    private void spellPopNoTabPage(AttrConfig conf) {
        try {
            Model model = cacheUtil.getModel(conf.getModelId()); // 根据模型id查询
            String tableName = conf.getTabNoName();//获取非动态模型的，手动输入的表名
            JspUtil.copyPopTempFile(model, conf.getAttrColumn());// 根据模型复制模板文件到直接路径下

            Map<String, String> modelIdMap = new HashMap<String, String>();
            modelIdMap.put("modelId", model.getId());

            String targetFilePath = JspUtil.getFilePath(model.getTableName(), conf.getAttrColumn() + "popList", "jsp"); // 根据业务名称加操作类型获取jsp地址
            String formatJspStr = ListJspCreate.spellPopNoTabJsp(conf.getDataSourceColumn(), model).toString(); // 拼接弹出页面单元格字符串

            ListJspCreate.createPopNoTabPage(formatJspStr, targetFilePath, model, tableName, conf.getAttrColumn(), "popList");

            String targetFilePathJs = JspUtil.getFilePath(model.getTableName(), conf.getAttrColumn() + "popList", "js"); // 拼接js页面内容

//			ListJsCreate.createPopJs(targetFilePathJs, tableName, getPopColumnsStr(configLst),conf.getAttrColumn(), "list");
            ListJsCreate.createNoTabPopJs(targetFilePathJs, model, tableName, getNoTabPopColumns(conf.getDataSourceColumn()), conf.getAttrColumn(), "list");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void spellTreeListPage(Model benModel, AttrConfig conf, List<AttrConfig> configLst, List<AttrConfig> treeConfigLst) {
        try {
            Model model = cacheUtil.getModel(conf.getModelId()); // 缓存里取

            Model sourceModel = cacheUtil.getModel(conf.getDataSourceTable()); // 根据模型id查询
            JspUtil.copyTreeFile(model, conf.getAttrColumn());// 根据模型复制模板文件到直接路径下

            Map<String, String> modelIdMap = new HashMap<String, String>();
            modelIdMap.put("modelId", model.getId());

            String targetFilePath = JspUtil.getFilePath(model.getTableName(), conf.getAttrColumn() + "treeList", "jsp"); // 根据业务名称加操作类型获取jsp地址
            String formatJspStr = ListJspCreate.spellSearchJsp(configLst, model).toString(); // 拼接弹出页面单元格字符串
            ListJspCreate.createTreeListPage(formatJspStr, targetFilePath, model, sourceModel.getTableName(),
                    conf.getAttrColumn(), "treeList");

            String targetFilePathJs = JspUtil.getFilePath(model.getTableName(), conf.getAttrColumn() + "treeList",
                    "js"); // 拼接js页面内容
            ListJsCreate.createTreeJs(benModel, targetFilePathJs, sourceModel, getPopColumnsStr(configLst), conf, treeConfigLst,
                    "treeList");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回级联查询的条件
     *
     * @return "c_001":"'+$("#c_001").val()+'"
     */
    private String casePopFilter(AttrConfig conf) {
        String caseSourceColumn = cacheUtil.getAttrConfig(conf.getDataSourceTable(), conf.getCascadedForeignKey())
                .getAttrColumn();
        AttrConfig ac = cacheUtil.getAttrConfig(conf.getModelId(), conf.getCascadedAttr());
        String selfColumn = ac.getAttrColumn(); // 获取模型自己关联的列

        String filterStr = "";
        if ("checkBoxType".equals(ac.getAttrType()) || "radioType".equals(ac.getAttrType())) { // 级联的列是下拉框
            filterStr = spellPopFilte(caseSourceColumn, selfColumn);
        } else {
            // 2018年1月13号，刘晶针对弹出框级联问题，添加此处
            filterStr = "pageReqeust." + caseSourceColumn.toLowerCase() + TableConst.FILTERSUFFIX + "=$(\'#" + selfColumn.toLowerCase() + "\').val()";

            //原有白艳荣做的一种（弹出框级联查询不好用）
//			filterStr = "pageReqeust.filter=\'{" + "\"" + caseSourceColumn.toLowerCase() + "\"" + ":" + "\"\'+"
//					+ "$(\'#" + selfColumn.toLowerCase() + "\').val()+'\"" + "}\'";
        }
        return filterStr;
    }

    private String spellPopFilte(String caseC, String self) {
        String str = "var obj=document.getElementsByName(\'" + self.toLowerCase() + "\');	\r\n";
        str += "var s='';	\r\n";
        str += "for(var i=0; i<obj.length; i++){	\r\n";
        str += "if(obj[i].checked){	\r\n";
        str += "if(''==s){	\r\n";
        str += "s=obj[i].value;	\r\n";
        str += "}else{	\r\n";
        str += "s+=','+obj[i].value	\r\n";
        str += "}	\r\n";
        str += "}	\r\n";
        str += "}	\r\n";
        str += "pageReqeust.filter=\'{" + caseC.toLowerCase() + ":\"\'+s+\'\"}\';";
        return str;
    }

    /**
     * 查询弹出框共用多少列的字符串
     *
     * @return
     */
    private String getPopColumnsStr(List<AttrConfig> configLst) {
        String str = "";
        for (AttrConfig config : configLst) {
            if ("" == str) {
                str = "data[0]." + config.getAttrColumn().toLowerCase();
            } else {
                str += "+'_'+" + "data[0]." + config.getAttrColumn().toLowerCase();
            }
        }
        return str;
    }

    /**
     * 查询弹出框共用多少列的字符串
     *
     * @return
     */
    private String getNoTabPopColumns(String columsStr) {
        String str = "";
        String colu[] = columsStr.split(",");
        for (int i = 0; i < colu.length; i++) {
            String col = colu[i];
            col = CameHumpInterceptor.underlineToCamelhump(col);
            if ("" == str) {
                str = "data[0]." + col;
            } else {
                str += "+'_'+" + "data[0]." + col;
            }
        }
        return str;
    }

    /**
     * 返回这个模型的属性类型，比如弹出框，树类型
     */
    private Map<String, Object> getAttrConfigByColumnType(List<AttrConfig> configLst) {
        Map<String, Object> result_map = new HashMap<>();
        //注释：for-加载所有弹出列表，是跟动态模型相关的，关联和级联（moduleType ==1 和 moduleType ==2  ）
        List<AttrConfig> popConfigLst = new ArrayList<AttrConfig>();
        //这是注释：for-加载所有列表树的属性列集合（针对属性设置），动态模型模块
        List<AttrConfig> treeConfigLst = new ArrayList<AttrConfig>();
        //注释：for-加载所有弹出列表，是跟动态模型无关，外部相关表数据来源（moduleType ==5  ）
        List<AttrConfig> popNoTabLst = new ArrayList<AttrConfig>();
        for (AttrConfig conf : configLst) {
            if ("popList".equals(conf.getAttrType())) {//关联或者级联属性设置
                if (conf.getModuleType().equals("1") || conf.getModuleType().equals("2")) {
                    popConfigLst.add(conf);
                } else if (conf.getModuleType().equals("5")) {//外部数据来源属性设置
                    popNoTabLst.add(conf);
                }
            }
            if ("listTree".equals(conf.getAttrType())) {
                conf.setDataSourceColumn(conf.getDataSourceColumn()); // 查询值来源列的id转换为列名
                treeConfigLst.add(conf);
            }
        }
        result_map.put("popNoTabLst", popNoTabLst);
        result_map.put("popList", popConfigLst);
        result_map.put("listTree", treeConfigLst);
        return result_map;
    }

    /**
     * 根据弹出框类型的列的数据来源表，查询数据来源表下面的属性配置，并拼写弹出框页面
     */
    private void columnPop(Model model) {
        //1.获取本模型所有属性设置集合
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());
        //2.获取，所有是弹出框的属性列的集合(针对动态模型生成的表)
        List<AttrConfig> popConfigLst = (List<AttrConfig>) getAttrConfigByColumnType(configLst).get("popList");
        //2.获取，所有是弹出框的属性列的集合(针对不是动态模型生成的表，例如，用户表-物料表等)
        List<AttrConfig> popNoTabLst = (List<AttrConfig>) getAttrConfigByColumnType(configLst).get("popNoTabLst");
        // 查询这个模型下是弹出框类型的列配置
        //先处理跟动态模型相关的弹出列表生成页面的方法
        for (AttrConfig conf : popConfigLst) {
            //（1.）定义一个集合，去存储（动态模型的关联和级联的弹出列表设置的属性集合）
            List<AttrConfig> resPopConfig = new ArrayList<AttrConfig>(); // 返回的结果
            for (String confCol : conf.getDataSourceColumn().split(",")) {
                AttrConfig attrConfig = cacheUtil.getAttrConfig(conf.getDataSourceTable(), confCol);
                resPopConfig.add(attrConfig);
            }
            //这是针对动态模型生成弹出列表的页面操作方法
            this.spellPopListPage(conf, resPopConfig);// 每一个弹出框类型的属性都生成一个弹出框页面
            resPopConfig.clear();

        }
        //然后处理跟动态模型无关的，从外部选择数据表的弹出列表生成页面方法
        for (AttrConfig cofig : popNoTabLst) {
            //生成外部引用表的弹出页面
            this.spellPopNoTabPage(cofig);
        }

    }

    /**
     * 根据树类型的列数据来源表，查询数据来源表下面的属性配置，并拼写页面
     */
    private void columTree(Model model) {
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());
        Map<String, String> map = new HashMap<String, String>();
        // 获取所有本模型是列表树的属性设置
        List<AttrConfig> treeConfigLst = (List<AttrConfig>) getAttrConfigByColumnType(configLst).get("listTree"); // 查询这个模型下是树类型的列配置
        List<AttrConfig> resTreeConfig = new ArrayList<AttrConfig>(); // 返回的结果
        List<String> confColLst = null; // 这个模型下配置的值来源列,用于集合contain判断
        List<AttrConfig> sourceTableconfigLst = this.getJspAttr("2", model);

        for (AttrConfig conf : treeConfigLst) {
            confColLst = new ArrayList<String>();
            map.put("modelId", conf.getDataSourceTable());
            for (String confCol : conf.getDataSourceColumn().split(",")) {
                confColLst.add(confCol); // 存储模型配置下这一列值来源列的列名
            }
            for (AttrConfig treeConf : sourceTableconfigLst) {
                if (confColLst.contains(treeConf.getAttrColumn())) {
                    resTreeConfig.add(treeConf);
                }
            }
            this.spellTreeListPage(model, conf, resTreeConfig, treeConfigLst);// 每一个弹出框类型的属性都生成一个弹出框页面
            resTreeConfig.clear();
        }
    }

    /**
     * 根据某一列的来源表的ID查询这一列的来源列
     */
    @Override
    public List<GenSelect> getColum(Map<String, String> map) {
        List<GenSelect> list = new ArrayList<GenSelect>();
        AttrConfig config = cacheUtil.getAttrConfig(map.get("modelId"), map.get("attrColumn"));
        Model model = cacheUtil.getModel(config.getDataSourceTable());
        map.put("sourceTable", model.getTableName());// 值来源表
        map.put("sourceCol", config.getDataSourceColumn().replace(",", "||'_'||"));// 值来源列
        map.put("caseColumn", "");
        list = genJspDao.getColumById(map);
        return list;
    }

    /**
     * *
     * <p>
     * Title: 选择设置时获取，设置的选择设置的结果，并解析
     * </p>
     *
     * @author : xiaoliu
     * @date :2016年8月8日下午2:30:16
     */
    private Map<String, Object> getSelected(Model model, String type) {
        Map<String, String> map = new HashMap<String, String>();
        // 生成选择设置的js
        StringBuilder sb = new StringBuilder();
        // 生成自定义编码的js
        StringBuilder gen = new StringBuilder();
        GenSelectType sel;
        List<GenSelectType> selLst = new ArrayList<GenSelectType>();
        List<String> columList = new ArrayList<String>();
        map.put("modelId", model.getId());
        List<AttrConfig> configAttrs = this.getJspAttr("2", model);
        for (int i = 0; i < configAttrs.size(); i++) {
            AttrConfig ac = configAttrs.get(i);
            // 选择设置（同过当前列的属性值，控制其他列是否显示）
            if ("3".equals(ac.getModuleType())) {///表示属性设置中是选择设置
                columList.add(ac.getAttrColumn());
                String selectedStr = ac.getSelectedConfigAttr(); // 获取关联的列的值字符串
                sb.append(getCheckCaseFunction(model.getId() + "", ac.getAttrColumn(), selectedStr));
                // 1:C_007|2:C_008|3:C_009|4:C_007,C_008
                String[] splitStr = selectedStr.split("@@"); // 根据|拆分 1:C_007
                // 2:C_008
                // 4:C_007,C_008
                for (int m = 0; m < splitStr.length; m++) {
                    sel = new GenSelectType();
                    sel.setCaseColumn(ac.getAttrColumn());
                    String[] splitId = splitStr[m].split(":"); // 将id和关联的列拆分1
                    // C_007 4
                    // C_007,C_008
                    sel.setCaseValue(splitId[0]);
                    sel.setCaseAttrs(splitId[1]);
                    selLst.add(sel); // 关联列 值 显示的属性列
                }
            } else if ("4".equals(ac.getModuleType()) && "1".equals(String.valueOf(ac.getSetCodeTime()))) { // 预先
                // 生成
                // 自定义编码
                // add
                // zhangtao
                // 属性列名
                String genCol = ac.getAttrColumn().toLowerCase();
                // 流水码长度
                // int waterLen = Integer.parseInt(ac.getWaterCodeLength());
                // 自定义编码
                String codeRule = ac.getCodeRule(); // 固定码@@属性列@@连接符
                String[] styles = codeRule.split("@@");
                String prefix = "undefined".equals(styles[0]) ? "" : styles[0]; // 固定码
                String column = styles[1]; // 属性列
                // 连接符
                String union = "undefined".equals(styles[2]) ? "" : styles[2];

                gen.append("$RN$ $scope.genAutoCode").append(genCol).append(" = function() { $RN$");
                // 自定义配码
                String autoCode = " $scope." + genCol;
                // 流水码的影藏域
                String autoCodeHidden = "$scope." + genCol + "_hidden";
                if ("edit".equals(type)) {
                    // 编辑则不需要调用后台来生成流水码
                    gen.append("$RN$ if(").append(autoCode).append("){ $RN$").append(autoCodeHidden).append(" = ")
                            .append(autoCode).append(".substring(").append(autoCode).append(".length - ")
                            .append(ac.getWaterCodeLength()).append("); ").append("$RN$ } $RN$ ");
                }

                gen.append(autoCode).append(" = '").append(prefix).append("' ");
                if (!"undefined".equals(column)) {
                    String[] cols = column.split(",");
                    for (String col : cols) {
                        // 过滤未赋值的列
                        gen.append("$RN$ if($scope.").append(col.toLowerCase()).append("){ $RN$").append(autoCode)
                                .append(" += '").append(union).append("' + $scope.").append(col.toLowerCase())
                                .append("; $RN$ } $RN$ ");
                    }
                }

                // 编辑则不需要调用后台
                gen.append("$RN$ if(").append(autoCodeHidden).append("){ $RN$").append(autoCode).append(" += '")
                        .append(union).append("' + ").append(autoCodeHidden).append("; $RN$ } else { ");
                gen.append("$RN$ $http({ ").append("$RN$ url : basePath+'").append(UrlConst.AUTOCODEURL).append("', ")
                        .append("$RN$ method : 'POST', ").append("$RN$ params : { ").append("$RN$ 'seqName' : '")
                        .append(TableConst.TABLEPREFIX).append(ac.getModelId()).append(genCol).append("',")
                        .append("$RN$ 'length' : ").append(ac.getWaterCodeLength()).append("$RN$ } ")
                        .append("$RN$ }).success(function(data, header, config, status) { ")
                        // 防止一条记录反复获取流水码
                        .append(autoCodeHidden).append(" = data; $RN$ ").append(autoCode).append(" += '").append(union)
                        .append("' + data ;").append("$RN$ }).error(function(data, header, config, status) { ")
                        .append("$RN$ 	console.log('数据加载失败！'); ").append("}); ").append("$RN$ }");
                gen.append("$RN$ };");
            }
        }
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("selLst", selLst);
        resMap.put("sb", sb.toString());
        resMap.put("autoCode", gen.toString().replace("$RN$", "\r\n"));
        resMap.put("columList", columList);
        return resMap;
    }

    private String getCheckCaseFunction(String modelId, String column, String caseAttr) {
        String function = "";
        Map<String, String> map = new HashMap<String, String>();
        Map<String, String> mapReturn = new HashMap<String, String>();

        map.put("modelId", modelId);
        String[] caseCol = caseAttr.split("@@");
        for (int i = 0; i < caseCol.length; i++) {
            String colNotNull = "";
            String[] splitCase = caseCol[i].split(":");
            for (int j = 0; j < splitCase[1].split(",").length; j++) {
                map.put("attrColumn", splitCase[1].split(",")[j]);
                AttrConfig ac = cacheUtil.getAttrConfig(modelId, splitCase[1].split(",")[j]);
                if (!ObjectUtils.isEmpty(ac)) {
                    if ("0".equals(String.valueOf(ac.getIsNull()))) { // 必填的
                        if ("".equals(colNotNull)) {
                            colNotNull = splitCase[1].split(",")[j];
                        } else {
                            colNotNull += "," + splitCase[1].split(",")[j];
                        }
                    }
                }

            }
            mapReturn.put(splitCase[0], colNotNull);
        }
        function = JspUtil.checkNgShow(column, mapReturn, caseAttr);
        return function;
    }

    @Override
    /**
     * <p>TODO</p>
     * @param : @param modelId == 本模型的modelId
     * @param : @return
     * @author : xiaoliu
     * @date :2017年7月8日上午7:42:18
     */
    public Map<String, Object> isHasSub(String modelId) {
        //定义从表结果集
        Map<String, Object> resCongMap = new HashMap<>();
        // 本模型--当前操作的模型
        Model model = cacheUtil.getModel(modelId); // 缓存中获取具体模型对象
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(modelId);// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(modelId);// 查询属性组
        //是否树
        Model fenModel = null;
        List<AttrConfig> fenConfigLst = new ArrayList<AttrConfig>();
        List<AttrGroup> fenGroupLst = new ArrayList<AttrGroup>();
        if (!model.getClassType().equals("0") && null != model.getMaintableId()) {
            fenModel = cacheUtil.getModel(model.getMaintableId()); // 左侧树的模型
            // 本模型，属性相关设置
            fenConfigLst = cacheUtil.getAttrList(model.getMaintableId());
            // 根据模型id将所有的属性组查询，为下面的方法调用
            fenGroupLst = attrGroupDao.queryGroupByModelId(model.getMaintableId());
        }
        // 查询从表
        List<Model> subModel = modelDao.isHasSub(modelId);
        boolean flag = false;// 默认模型没有从表
        if (!subModel.isEmpty()) {
            for (Model m : subModel) {
                // 从表没有建立实体
                if (m.getIsTableCreate() == 0) {
                    resCongMap.put("isReady", "false");
                    return resCongMap;
                }
            }
            flag = true;
        }
        resCongMap.put("fenModel", fenModel);//分类树模型
        resCongMap.put("fenConfigLst", fenConfigLst);//分类树属性设置
        resCongMap.put("fenGroupLst", fenGroupLst);//分类树属性组设置
        resCongMap.put("benConfigLst", configLst);
        resCongMap.put("benGroupLst", groupLst);
        resCongMap.put("subModel", subModel);
        resCongMap.put("flag", flag);
        return resCongMap;
    }

    /**
     * 查询视图
     */
    @Override
    public List<AttrGroup> queryGroupByModelId(String busId) {
        List<AttrGroup> groupLst = new ArrayList<AttrGroup>();
        SysBusiness buss = new SysBusiness();
        buss.setBusId(busId);
        String tableName = sysBusinessDao.queryBusById(buss).getBusTable();
        String modelId = tableName.substring(tableName.indexOf("_") + 1, 6);
        List<AttrGroup> groupZa = attrGroupDao.queryGroupByModelId(modelId);// 查询属性组
        List<AttrConfig> moAtrLst = cacheUtil.getAttrListByGroup(modelId, null);
        if (moAtrLst.size() > 0) {
            AttrGroup group = new AttrGroup();
            group.setId("0");
            group.setModelId(modelId);
            group.setGroupName("默认属性组");
            group.setPosition(0);
            groupLst.add(group);
        }
        for (int i = 0; i < groupZa.size(); i++) {
            AttrGroup group = groupZa.get(i);
            groupLst.add(group);
        }

        return groupLst;
    }

    @Override
    public void createDisJsp(String modelId) {
        Model model = cacheUtil.getModel(modelId); // 缓存中获取具体模型对象
        if (0 == model.getIsJspCreate()) {// 已经创建了页面
            throw new RuntimeException("该模型未生成页面,不能创建分发查询页面！");
        }
        if (0 == model.getIsWorkflow()) {
            throw new RuntimeException("该模型未配置流程,不需要创建分发查询页面！");
        }
        if ("1" == model.getModelType()) {// 模型类型 【0-主数据、1-字典表】
            throw new RuntimeException("字典表不需要创建分发查询页面！");
        }
        String filePathJsp = PlatForm.getAbsolutePath() + "am/" + model.getTableName() + "/" + model.getTableName() + "_disList.jsp";
        File fileJsp = new File(filePathJsp);
        if (fileJsp.exists()) {
            fileJsp.delete();//存在删除
        }
        String filePathJs = PlatForm.getAbsolutePath() + "am/" + model.getTableName() + "/js/" + model.getTableName() + "_disList.js";
        File fileJs = new File(filePathJs);
        if (fileJs.exists()) {
            fileJs.delete();//存在删除
        }
        Map<String, Object> isHasSubMap = isHasSub(modelId);

        //拷贝页面
        JspUtil.copyTempDisFile(model);// 根据模型复制模板文件到直接路径下
        this.createListDisJsp(model, isHasSubMap);//替换模板文件

    }
/**===============列表模板生成页面方法-----开始 ===================================================================*/
    /**
     * TODO 生成列表(非多视图列表)页面方法
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型类型 【0-主数据、1-字典表】
        String modelType = model.getModelType();

        for (String type : JspUtil.getPagesByModelType(modelType)) { // 拼接jsp页面内容
            if ("1".equals(type)) { // 生成查询页面
                this.createListSearchJsp(model, isHasSubMap);
            } else if ("2".equals(type)) {
                this.createListApplyJsp(model, isHasSubMap);
            } else if ("add".equals(type)) { // 添加新增动态生成新增按钮页面
                this.createListAddJsp(model, isHasSubMap);
            } else if ("edit".equals(type)) {
                this.createListEditJsp(model, isHasSubMap);
            } else if ("approve".equals(type)) {
                this.createListApproveJsp(model, isHasSubMap);
            } else if ("wh".equals(type)) { // 生成维护页面
                this.createListWhJsp(model, isHasSubMap);
            } else if ("update".equals(type)) {
                this.createListUpdateJsp(model, isHasSubMap);
            } else if ("updateHis".equals(type)) { // 生成变更历史查询页面
                this.createListUpdateHisJsp(model, isHasSubMap);
            } else if ("updateEdit".equals(type)) { // 生成变更页面的编辑页面
                this.createListUpdateEditJsp(model, isHasSubMap);
            } else if ("batchImport".equals(type)) { // 生成批量导入页面
                this.createListBatchImportJsp(model, isHasSubMap);
            } else if ("detail".equals(type)) { // 生成详细页面
                this.createListDetailJsp(model, isHasSubMap);
            }
        }
    }


    // 生成多视图列表页面
    public void createListViewJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型类型 【0-主数据、1-字典表】
        String modelType = model.getModelType();

        for (String type : JspUtil.getPagesByModelType(modelType)) { // 拼接jsp页面内容
            if ("1".equals(type)) { // 生成查询页面
                this.createListSearchJsp(model, isHasSubMap);
            } else if ("2".equals(type)) {//生成申请页面
                this.createListApplyJsp(model, isHasSubMap);
            } else if ("add".equals(type)) { // 添加新增动态生成新增按钮页面
                this.createListAddJsp(model, isHasSubMap);
            } else if ("edit".equals(type)) {
                this.createListEditJsp(model, isHasSubMap);
            } else if ("approve".equals(type)) {
                this.createListApproveJsp(model, isHasSubMap);
            } else if ("wh".equals(type)) { // 生成维护页面
                this.createListWhJsp(model, isHasSubMap);
            } else if ("update".equals(type)) {
                this.createListUpdateJsp(model, isHasSubMap);
            } else if ("updateHis".equals(type)) { // 生成变更历史查询页面
                this.createListUpdateHisJsp(model, isHasSubMap);
            } else if ("updateEdit".equals(type)) { // 生成变更页面的编辑页面
                this.createListUpdateEditJsp(model, isHasSubMap);
            } else if ("batchImport".equals(type)) { // 生成批量导入页面
                this.createListBatchImportJsp(model, isHasSubMap);
            } else if ("detail".equals(type)) { // 生成详细页面
                this.createListDetailJsp(model, isHasSubMap);
            }
        }
    }

    /**
     * 生成分发日志查询页面
     *
     * @param model
     * @param isHasSubMap
     */
    private void createListDisJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型类型 【0-主数据、1-字典表】

        String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();
        String jspPath;
        if ("0".equals(modelType)) {
            // 生成list jsp
            jspPath = JspUtil.getFilePath(tableName, "disList", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
            // 分发日志查询页面
            List<AttrConfig> jspAttrLst = this.getJspAttr("1", model);
            String str = ListJspCreate.spellDisSearchJsp(jspAttrLst, model);
            ListJspCreate.createListPage(model, str, jspPath, "disList");


            // 生成list js
            jspPath = JspUtil.getFilePath(tableName, "disList", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容

            ListJsCreate.createSearchJs(jspPath, model, "disList");
        }

    }

    /**
     * TODO 生成公用列表模板查询页面的方法页面方法=====针对列表模板的查询页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListSearchJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型类型 【0-主数据、1-字典表】
        String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();
        String jspPath;
        if ("0".equals(modelType)) {
            // 生成list jsp
            jspPath = JspUtil.getFilePath(tableName, "list", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
            // 拼接的不是查询页面，是列表页面 type=1
            String formatJspStr = spellJspStr("1", model); // 拼接查询页面单元格字符串
            ListJspCreate.createListPage(model, formatJspStr, jspPath, "list");
            // 生成list js
            jspPath = JspUtil.getFilePath(tableName, "list", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            ListJsCreate.createSearchJs(jspPath, model, "list");
        } else {
            // 生成list jsp
            jspPath = JspUtil.getFilePath(tableName, "zdList", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
            // 拼接的不是查询页面，是列表页面 type=1
            String formatJspStr = spellJspStr("1", model); // 拼接查询页面单元格字符串
            ListJspCreate.createListPage(model, formatJspStr, jspPath, "zdList");
            // 生成list js
            jspPath = JspUtil.getFilePath(tableName, "zdList", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            ListJsCreate.createSearchJs(jspPath, model, "list");
        }

        //生成查页面的时候，同时生成一套归档页面


    }

    /**
     * TODO 生成公用列表模板申请页面的方法页面方法=====针对列表模板的申请页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListApplyJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        boolean bool = (boolean) isHasSubMap.get("flag");

        // 生成申请页面apply // 拼接的不是申请页面，是列表页面 type=1
        String jspPath = JspUtil.getFilePath(tableName, "apply", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
        String jspStr = spellJspStr("4", model); // 拼接查询页面单元格字符串
        ListJspCreate.createApplyPage(model, jspStr, jspPath, "apply");

        // 拼接的不是申请页面，是查看详情页面 type=4
        String jspPathDetail = JspUtil.getFilePath(tableName, "applyDetail", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
        String jspStrDetail = spellJspStrDetail("4", model);
        ListJspCreate.createListDetailPage(model, jspStrDetail, jspPathDetail, tableName, "applyDetail");

        //生成申请页面js
        String jsStr = JspUtil.getFilePath(tableName, "apply", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createApplyJs(jsStr, model, "apply", bool, configLst);

        //生成申请详情页面js
        String jsDetail = JspUtil.getFilePath(tableName, "applyDetail", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createApplyJs(jsDetail, model, "applyDetail", bool, configLst);
    }

    /**
     * TODO 生成公用列表模板新增页面的方法页面方法=====针对列表模板的新增页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListAddJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组

        if (model.getIsMoreView() == 1) {//如果是多视图
            String addJsp = JspUtil.getFilePath(tableName, "add", JspUtil.spellReJsp(model, "0"));// 根据业务名称加操作类型获取jsp地址(新增地址)
            // 注意：新增和申请页面对应的type 都为"2"
            String addStr = this.spellViewAddStr("2", model, "add", isHasSubMap); // 拼接查询页面单元格字符串
            // 新增页面入口
            AddJspCreate.createTreeTabViewAddPage(addStr, addJsp, model, "add", "apply", isHasSubMap, groupLst, configLst);


            // 新增页面动态生成js文件入口
            String addJs = JspUtil.getFilePath(tableName, "add", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "add");
            AddJsCreate.createAddJs(res_Map, addJs, model, resMap, "add", "apply", isHasSubMap, null, groupLst);
        } else {
            String addJsp = JspUtil.getFilePath(tableName, "add", JspUtil.spellReJsp(model, "0"));// 根据业务名称加操作类型获取jsp地址(新增地址)
            // 注意：新增和申请页面对应的type 都为"2"
            String addStr = this.spellJspAddStr("2", model, null, groupLst, configLst); // 拼接查询页面单元格字符串
            // 新增页面入口
            AddJspCreate.createAddPage(addStr, addJsp, model, "add", "apply", isHasSubMap);


            // 新增页面动态生成js文件入口
            String addJs = JspUtil.getFilePath(tableName, "add", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "add");
            AddJsCreate.createAddJs(res_Map, addJs, model, resMap, "add", "apply", isHasSubMap, null, groupLst);
        }
    }

    /**
     * TODO 生成公用列表模板申请页面编辑页面的方法页面方法=====针对列表模板的申请页面编辑
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListEditJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组

        boolean bool = (boolean) isHasSubMap.get("flag");

        if (model.getIsMoreView() == 1) {//表示是多视图
            // 生成修改页面
            String editJsp = JspUtil.getFilePath(tableName, "edit", JspUtil.spellReJsp(model, "0"));// 根据业务名称加操作类型获取jsp地址(新增地址)
            String editStr = spellViewAddStr("2", model, "edit", isHasSubMap); // 拼接查询页面单元格字符串
            EditJspCreate.createViewEditPage(editStr, editJsp, model, "edit", "apply", isHasSubMap, groupLst, configLst);


            Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "edit");
            String editJs = JspUtil.getFilePath(tableName, "edit", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            EditJsCreate.creatEditJs(res_Map, editJs, model, resMap, "edit", "apply", isHasSubMap, bool, groupLst);
        } else {
            // 生成修改页面
            String editJsp = JspUtil.getFilePath(tableName, "edit", JspUtil.spellReJsp(model, "0"));// 根据业务名称加操作类型获取jsp地址(新增地址)
            String editStr = spellJspAddStr("2", model, "edit", groupLst, configLst); // 拼接查询页面单元格字符串
            EditJspCreate.createEditPage(editStr, editJsp, model, "edit", "apply", isHasSubMap);

            Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "edit");
            String editJs = JspUtil.getFilePath(tableName, "edit", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            EditJsCreate.creatEditJs(res_Map, editJs, model, resMap, "edit", "apply", isHasSubMap, bool, groupLst);
        }


    }

    /**
     * TODO 生成公用列表模板审核编辑页面的方法页面方法=====针对列表模板的审核页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListApproveJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息

        // 生成审核页面sh
        String shJsp = JspUtil.getFilePath(tableName, "approve", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
        // 拼接的不是审核页面，是列表页面 type=1
        String shStr = spellJspStr("1", model); // 拼接查询页面单元格字符串
        ListJspCreate.createListPage(model, shStr, shJsp, "approve");

        String shJs = JspUtil.getFilePath(tableName, "approve", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createShJs(shJs, model, "approve", isHasSubMap, configLst);

    }

    /**
     * TODO 生成公用列表模板审核页面的方法页面方法=====针对列表模板的审核页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListWhJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息

        String whJsp = JspUtil.getFilePath(tableName, "wh", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
        String whStr = spellJspStr("1", model); // 拼接维护页面单元格字符串，维护页面和查询页面显示的字段相同
        ListJspCreate.createListPage(model, whStr, whJsp, "wh");

        String whJs = JspUtil.getFilePath(tableName, "wh", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createWhJs(whJs, model, "wh", configLst);

    }

    /**
     * TODO 生成公用列表模板变更页面的方法页面方法=====针对列表模板的变更页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListUpdateJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组

        // 生成变更页面
        String updateJsp = JspUtil.getFilePath(tableName, "update", JspUtil.spellReJsp(model, "0"));
        // 拼接的不是修改页面，是列表页面 type=1
        String updateStr = spellJspStr("1", model);
        ListJspCreate.createListPage(model, updateStr, updateJsp, "update");

        String updateJs = JspUtil.getFilePath(tableName, "update", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createBgJs(updateJs, model, "update", isHasSubMap, configLst);
        if ("0".equals(model.getClassType()) && !StringUtils.isBlank(model.getMaintableId())) {
            String subAddJsp = this.spellJspAddStr("2", model, null, groupLst, configLst); // 拼接查询页面单元格字符串
            spellSubAddPage(model, subAddJsp, "updateAdd", "update", configLst, groupLst);// 生成从表变更页面的新增
        } else {
            spellUpdatePopPage(model, "update", "bgPopList");// 生成变更页面的弹出框页面
        }
    }

    /**
     * TODO 生成公用列表模板变更历史页面的方法页面方法=====针对列表模板的变更历史页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListUpdateHisJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        String updateHisJsp = JspUtil.getFilePath(tableName, "updateHis", JspUtil.spellReJsp(model, "0"));
        String updateHisStr = spellupdateHisJspStr("1", model);
        ListJspCreate.createUpdageHisPage(updateHisStr, updateHisJsp, model, "updateHis");

        String updateHisJs = JspUtil.getFilePath(tableName, "updateHis", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createUpdateHisJs(updateHisJs, model, "updateHis");
    }

    /**
     * TODO 生成公用列表模板变更页面编辑页面的方法页面方法=====针对列表模板的变更页面编辑
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListUpdateEditJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组

        boolean bool = (boolean) isHasSubMap.get("flag");

        if (model.getIsMoreView() == 1) {
            String updateEditJsp = JspUtil.getFilePath(tableName, "updateEdit", JspUtil.spellReJsp(model, "0"));
            String updateEditStr = spellViewAddStr("3", model, "updateEdit", isHasSubMap); // 拼接查询页面单元格字符串
            EditJspCreate.createViewEditPage(updateEditStr, updateEditJsp, model, "updateEdit", "update", isHasSubMap, groupLst, configLst);

            String updateEditJs = JspUtil.getFilePath(tableName, "updateEdit", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("3", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "updateEdit");
            EditJsCreate.creatEditJs(res_Map, updateEditJs, model, resMap, "updateEdit", "update", isHasSubMap, bool, groupLst);
        } else {
            String updateEditJsp = JspUtil.getFilePath(tableName, "updateEdit", JspUtil.spellReJsp(model, "0"));
            String updateEditStr = spellJspAddStr("3", model, "updateEdit", groupLst, configLst); // 拼接查询页面单元格字符串
            EditJspCreate.createEditPage(updateEditStr, updateEditJsp, model, "updateEdit", "update", isHasSubMap);

            String updateEditJs = JspUtil.getFilePath(tableName, "updateEdit", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("3", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "updateEdit");
            EditJsCreate.creatEditJs(res_Map, updateEditJs, model, resMap, "updateEdit", "update", isHasSubMap, bool, groupLst);
        }


    }

    /**
     * TODO 生成公用列表模板查看详情页面的方法=====针对列表模板的查看详情页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListDetailJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组


        String detailJsp = JspUtil.getFilePath(tableName, "detail", JspUtil.spellReJsp(model, "0"));
        String detailStr = spellJspDetailStr("4", model, "detail", groupLst, configLst); // 拼接查询页面单元格字符串
        DetailJspCreate.createDetailPage(detailStr, detailJsp, model, "detail", isHasSubMap, configLst);
        String checkFilesPage = JspUtil.getFilePath(tableName, "checkFiles", JspUtil.spellReJsp(model, "0"));
        DetailJspCreate.createCheckFilesPage(checkFilesPage, model, "checkFiles");

        String detailJs = JspUtil.getFilePath(tableName, "detail", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        DetailJsCreate.creatDetailJs(detailJs, model, configLst, "detail", isHasSubMap);
        String checkFilesJs = JspUtil.getFilePath(tableName, "checkFiles", JspUtil.spellReJsp(model, "1"));// 拼接查看附件页面
        DetailJsCreate.createCheckFilesJs(checkFilesJs, model);

    }

    /**
     * TODO 生成公用列表模板导人模板的页面=====针对列表模板的导人模板页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createListBatchImportJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        String importJsp = JspUtil.getFilePath(tableName, "batchImport", JspUtil.spellReJsp(model, "0"));
        ListJspCreate.createBatchImportPage(importJsp, model, "batchImport");

        String importJs = JspUtil.getFilePath(tableName, "batchImport", JspUtil.spellReJsp(model, "1"));
        ListJsCreate.createBatchImportJs(importJs, model, "apply");

    }
/**===============列表模板生成页面方法-----结束  =======================================================*/

/**===============树模板生成页面方法-----开始  =======================================================*/
    /**
     * TODO 生成树(非多视图)页面的方法
     *
     * @param model
     * @param result_map
     * @author : xiaoliu
     * @date :2017年6月29日下午3:26:05
     */
    public void createTreeJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型类型 【0-主数据、1-字典表】
        String modelType = model.getModelType();

        for (String type : JspUtil.getPagesByModelType(modelType)) { // 拼接jsp页面内容
            if ("main".equals(type)) {
                this.createTreeMainJsp(model, isHasSubMap);
            } else if ("1".equals(type)) { // 生成树查询页面
                this.createTreeSearchJsp(model, isHasSubMap);
            } else if ("2".equals(type)) { // 生成申请页面
                this.createTreeApplyJsp(model, isHasSubMap);
            } else if ("add".equals(type)) { // 添加新增动态生成新增按钮页面
                this.createTreeAddJsp(model, isHasSubMap);
            } else if ("edit".equals(type)) { // 生成修改页面
                this.createTreeEditJsp(model, isHasSubMap);
            } else if ("approve".equals(type)) { // 生成审核页面
                this.createTreeApproveJsp(model, isHasSubMap);
            } else if ("wh".equals(type)) { // 生成维护页面
                this.createTreeWhJsp(model, isHasSubMap);
            } else if ("update".equals(type)) { // 生成变更页面
                this.createTreeUpdateJsp(model, isHasSubMap);
            } else if ("updateHis".equals(type)) { // 生成变更历史查询页面
                this.createTreeUpdateHisJsp(model, isHasSubMap);
            } else if ("updateEdit".equals(type)) { // 生成变更页面的编辑页面
                this.createTreeUpdateEditJsp(model, isHasSubMap);
            } else if ("batchImport".equals(type)) {// 生成批量导入页面
                this.createTreeBathImportJsp(model, isHasSubMap);
            } else if ("detail".equals(type)) {// 生成详细页面
                this.createTreeDetailJsp(model, isHasSubMap);
            }
        }
    }

    /**
     * TODO 多视图生成页面
     *
     * @param model
     * @param isHasSubMap
     * @author : xiaoliu
     * @date :2017年6月29日下午5:28:28
     */
    public void createTreeViewJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型类型 【0-主数据、1-字典表】
        String modelType = model.getModelType();

        for (String type : JspUtil.getPagesByModelType(modelType)) { // 拼接jsp页面内容
            if ("main".equals(type)) {
                this.createTreeMainJsp(model, isHasSubMap);
            } else if ("1".equals(type)) { // 生成树查询页面
                this.createTreeSearchJsp(model, isHasSubMap);
            } else if ("2".equals(type)) { // 生成申请页面
                this.createTreeApplyJsp(model, isHasSubMap);
            } else if ("add".equals(type)) { // 添加新增动态生成新增按钮页面
                this.createTreeAddJsp(model, isHasSubMap);
            } else if ("edit".equals(type)) { // 生成修改页面
                this.createTreeEditJsp(model, isHasSubMap);
            } else if ("approve".equals(type)) { // 生成审核页面
                this.createTreeApproveJsp(model, isHasSubMap);
            } else if ("wh".equals(type)) { // 生成维护页面
                this.createTreeWhJsp(model, isHasSubMap);
            } else if ("update".equals(type)) { // 生成变更页面
                this.createTreeUpdateJsp(model, isHasSubMap);
            } else if ("updateHis".equals(type)) { // 生成变更历史查询页面
                this.createTreeUpdateHisJsp(model, isHasSubMap);
            } else if ("updateEdit".equals(type)) { // 生成变更页面的编辑页面
                this.createTreeUpdateEditJsp(model, isHasSubMap);
            } else if ("batchImport".equals(type)) {// 生成批量导入页面
                this.createTreeBathImportJsp(model, isHasSubMap);
            } else if ("detail".equals(type)) {// 生成详细页面
                this.createTreeDetailJsp(model, isHasSubMap);
            }
        }
    }


    /**
     * TODO 生成公用树模板左侧树页面的方法页面方法=====针对树模板的做测试页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeMainJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息

        boolean bool = (boolean) isHasSubMap.get("flag");

        Model fenModel = null;
        if (null != model.getMaintableId()) {
            fenModel = cacheUtil.getModel(model.getMaintableId()); // 左侧树的模型
            // 本模型，属性相关设置
            // List<AttrConfig> fenConfigLst=cacheUtil.getAttrList(model.getMaintableId());
            // 根据模型id将所有的属性组查询，为下面的方法调用
            //  List<AttrGroup> fenGroupLst=attrGroupDao.queryGroupByModelId(model.getMaintableId());
        }
        String mainJsp = JspUtil.getFilePath(tableName, "treeTabMain", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
        // 拼接的不是申请页面，是列表页面 type=1
        ListJspCreate.createTreeTabMainPage(mainJsp, model, fenModel, "treeTabMain", configLst);

        String mainJs = JspUtil.getFilePath(tableName, "treeTabMain", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createTreeTabMainJs(mainJs, model, fenModel, "treeTabMain", bool, configLst);
    }

    /**
     * TODO 生成公用树模板查询页面的方法页面方法=====针对树模板的查询页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeSearchJsp(Model model, Map<String, Object> isHasSubMap) {
        //主数据类型==主数据或者字典
        String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息

        String listJsp;
        if ("0".equals(modelType)) {// 主数据树
            listJsp = JspUtil.getFilePath(tableName, "treeTabList", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
            // 拼接的不是查询页面，是列表页面 type=1
            String listStr = spellJspStr("1", model); // 拼接查询页面单元格字符串
            ListJspCreate.createTreeTabListPage(listStr, listJsp, model, "treeTabList");

            String listJs = JspUtil.getFilePath(tableName, "treeTabList", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            ListJsCreate.createTreeTabSearchJs(listJs, model, "treeTabList", configLst);
        } else {
            listJsp = JspUtil.getFilePath(tableName, "treeTabZdList", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
            String listStr = spellJspStr("1", model); // 拼接查询页面单元格字符串
            ListJspCreate.createTreeTabListPage(listStr, listJsp, model, "treeTabZdList");

            String listJs = JspUtil.getFilePath(tableName, "treeTabZdList", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            ListJsCreate.createTreeTabSearchJs(listJs, model, "treeTabZdList", configLst);
        }

    }

    /**
     * TODO 生成公用树模板申请页面的方法页面方法=====针对树模板的申请页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeApplyJsp(Model model, Map<String, Object> isHasSubMap) {
        //主数据类型==主数据或者字典
        //	String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();

        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息

        boolean bool = (boolean) isHasSubMap.get("flag");

        String applyJsp = JspUtil.getFilePath(tableName, "treeTabApply", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
        // 拼接的不是申请页面，是列表页面 type=1
        String applyStr = spellJspStr("4", model); // 拼接查询页面单元格字符串
        ListJspCreate.createTreeTabListPage(applyStr, applyJsp, model, "treeTabApply");

        String applyJs = JspUtil.getFilePath(tableName, "treeTabApply", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createTreeTabApplyJs(applyJs, model, "treeTabApply", bool, configLst);

    }

    /**
     * TODO 生成公用树模板详情页面的方法页面方法=====针对树模板的详情页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeDetailJsp(Model model, Map<String, Object> isHasSubMap) {

        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组

        String detailJsp = JspUtil.getFilePath(tableName, "treeTabDetail", JspUtil.spellReJsp(model, "0"));
        String detailStr = spellJspDetailStr("4", model, "treeTabDetail", groupLst, configLst); // 拼接查询页面单元格字符串
        DetailJspCreate.createDetailPage(detailStr, detailJsp, model, "treeTabDetail", isHasSubMap, configLst);
        String checkFilesPage = JspUtil.getFilePath(tableName, "treeTabCheckFiles",
                JspUtil.spellReJsp(model, "0"));
        DetailJspCreate.createCheckFilesPage(checkFilesPage, model, "treeTabCheckFiles");

        String detaulJs = JspUtil.getFilePath(tableName, "treeTabDetail", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        DetailJsCreate.creatDetailJs(detaulJs, model, configLst, "treeTabDetail", isHasSubMap);
        String checkFilesJs = JspUtil.getFilePath(tableName, "treeTabCheckFiles",
                JspUtil.spellReJsp(model, "1"));// 拼接查看附件页面
        DetailJsCreate.createCheckFilesJs(checkFilesJs, model);

    }


    /**
     * TODO 生成公用树模板导入功能用到的模板页面=====针对树模板的导入功能的模板页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeBathImportJsp(Model model, Map<String, Object> isHasSubMap) {
        // 模型实体表名
        String tableName = model.getTableName();

        String importJsp = JspUtil.getFilePath(tableName, "treeBatchImport", JspUtil.spellReJsp(model, "0"));
        ListJspCreate.createBatchImportPage(importJsp, model, "treeBatchImport");

        String importJs = JspUtil.getFilePath(tableName, "treeBatchImport", JspUtil.spellReJsp(model, "1"));
        ListJsCreate.createBatchImportJs(importJs, model, "treeTabApply");

    }

    /**
     * TODO 生成公用树模板变更编辑模板页面=====针对树模板的变更编辑页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeUpdateEditJsp(Model model, Map<String, Object> isHasSubMap) {

        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组
        boolean bool = (boolean) isHasSubMap.get("flag");

        if (model.getIsMoreView() == 1) {
            String updateEditJsp = JspUtil.getFilePath(tableName, "treeTabUpdateEdit", JspUtil.spellReJsp(model, "0"));
            String updateEditStr = spellViewAddStr("3", model, "updateEdit", isHasSubMap); // 拼接查询页面单元格字符串
            EditJspCreate.createTreeTabViewEditPage(updateEditStr, updateEditJsp, model, "treeTabUpdateEdit", "treeTabUpdate", isHasSubMap, groupLst, configLst);

            String updateEditJs = JspUtil.getFilePath(tableName, "treeTabUpdateEdit", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("3", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "updateEdit");
            EditJsCreate.creatEditJs(res_Map, updateEditJs, model, resMap, "treeTabUpdateEdit", "treeTabUpdate", isHasSubMap, bool, groupLst);
        } else {
            String updateEditJsp = JspUtil.getFilePath(tableName, "treeTabUpdateEdit", JspUtil.spellReJsp(model, "0"));
            String updateEditStr = spellJspAddStr("3", model, "updateEdit", groupLst, configLst); // 拼接查询页面单元格字符串
            EditJspCreate.createTreeTabEditPage(updateEditStr, updateEditJsp, model, "treeTabUpdateEdit", "treeTabUpdate", isHasSubMap);

            String updateEditJs = JspUtil.getFilePath(tableName, "treeTabUpdateEdit", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("3", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "updateEdit");
            EditJsCreate.creatEditJs(res_Map, updateEditJs, model, resMap, "treeTabUpdateEdit", "treeTabUpdate", isHasSubMap, bool, groupLst);
        }

    }

    /**
     * TODO 生成公用树模板变更历史=====针对树模板的变更历史页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeUpdateHisJsp(Model model, Map<String, Object> isHasSubMap) {
        //主数据类型==主数据或者字典
        //	String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();

        String updateHisJsp = JspUtil.getFilePath(tableName, "treeTabUpdateHis", JspUtil.spellReJsp(model, "0"));
        String updateHisStr = spellupdateHisJspStr("1", model);
        ListJspCreate.createUpdageHisPage(updateHisStr, updateHisJsp, model, "treeTabUpdateHis");

        String updateHisJs = JspUtil.getFilePath(tableName, "treeTabUpdateHis", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createUpdateHisJs(updateHisJs, model, "treeTabUpdateHis");

    }

    /**
     * TODO 生成公用树模板变更=====针对树模板的变更页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeUpdateJsp(Model model, Map<String, Object> isHasSubMap) {

        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        String updateJsp = JspUtil.getFilePath(tableName, "treeTabUpdate", JspUtil.spellReJsp(model, "0"));
        // 拼接的不是申请页面，是列表页面 type=1
        String updateStr = spellJspStr("1", model);
        ListJspCreate.createListPage(model, updateStr, updateJsp, "treeTabUpdate");

        String updateJs = JspUtil.getFilePath(tableName, "treeTabUpdate", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createBgJs(updateJs, model, "treeTabUpdate", isHasSubMap, configLst);
        spellUpdatePopPage(model, "update", "bgPopList");

    }

    /**
     * TODO 生成公用树模版，新增=====针对树模板的新增页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeAddJsp(Model model, Map<String, Object> isHasSubMap) {
        //主数据类型==主数据或者字典
        //	String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组

        if (model.getIsMoreView() == 1) {//如果是多视图
            String addJsp = JspUtil.getFilePath(tableName, "treeTabAdd", JspUtil.spellReJsp(model, "0"));// 根据业务名称加操作类型获取jsp地址(新增地址)
            // 注意：新增和申请页面对应的type 都为"2"
            String addStr = this.spellTreeAddStr("2", model, "treeTabAdd", isHasSubMap);

            AddJspCreate.createTreeTabViewAddPage(addStr, addJsp, model, "treeTabAdd", "treeTabApply", isHasSubMap, groupLst, configLst);

            String addJs = JspUtil.getFilePath(tableName, "treeTabAdd", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "add");
            AddJsCreate.createAddJs(res_Map, addJs, model, resMap, "treeTabAdd", "treeTabApply", isHasSubMap, null, groupLst);
        } else {
            String addJsp = JspUtil.getFilePath(tableName, "treeTabAdd", JspUtil.spellReJsp(model, "0"));// 根据业务名称加操作类型获取jsp地址(新增地址)
            // 注意：新增和申请页面对应的type 都为"2"
            String addStr = this.spellJspAddStr("2", model, null, groupLst, configLst); // 拼接查询页面单元格字符串
            // 新增页面入口
            AddJspCreate.createTreeTabAddPage(addStr, addJsp, model, "treeTabAdd", "treeTabApply", isHasSubMap);

            String addJs = JspUtil.getFilePath(tableName, "treeTabAdd", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "add");
            AddJsCreate.createAddJs(res_Map, addJs, model, resMap, "treeTabAdd", "treeTabApply", isHasSubMap, null, groupLst);
        }
    }

    /**
     * TODO 生成公用树模板申请页面编辑=====针对树模板的申请页面编辑
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeEditJsp(Model model, Map<String, Object> isHasSubMap) {
        //主数据类型==主数据或者字典
        //	String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息
        // 本模型相关视图设置
        List<AttrGroup> groupLst = attrGroupDao.queryGroupByModelId(model.getId());// 查询属性组
        boolean bool = (boolean) isHasSubMap.get("flag");

        if (model.getIsMoreView() == 1) {
            String editJsp = JspUtil.getFilePath(tableName, "treeTabEdit", JspUtil.spellReJsp(model, "0"));// 根据业务名称加操作类型获取jsp地址(新增地址)
            String editStr = spellViewAddStr("2", model, "edit", isHasSubMap); // 拼接查询页面单元格字符串
            EditJspCreate.createTreeTabViewEditPage(editStr, editJsp, model, "treeTabEdit", "treeTabApply", isHasSubMap, groupLst, configLst);

            String editJs = JspUtil.getFilePath(tableName, "treeTabEdit", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "edit");
            EditJsCreate.creatEditJs(res_Map, editJs, model, resMap, "treeTabEdit", "treeTabApply", isHasSubMap, bool, groupLst);
        } else {
            String editJsp = JspUtil.getFilePath(tableName, "treeTabEdit", JspUtil.spellReJsp(model, "0"));// 根据业务名称加操作类型获取jsp地址(新增地址)
            String editStr = spellJspAddStr("2", model, "edit", groupLst, configLst); // 拼接查询页面单元格字符串
            EditJspCreate.createTreeTabEditPage(editStr, editJsp, model, "treeTabEdit", "treeTabApply", isHasSubMap);

            String editJs = JspUtil.getFilePath(tableName, "treeTabEdit", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
            Map<String, Object> resMap = this.getEditJspAttr("2", model.getId(), configLst);
            Map<String, Object> res_Map = this.getSelected(model, "edit");
            EditJsCreate.creatEditJs(res_Map, editJs, model, resMap, "treeTabEdit", "treeTabApply", isHasSubMap, bool, groupLst);
        }

    }

    /**
     * TODO 生成公用树模板审核=====针对树模板的审核页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeApproveJsp(Model model, Map<String, Object> isHasSubMap) {
        //主数据类型==主数据或者字典
        //	String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息

        String shJsp = JspUtil.getFilePath(tableName, "treeTabApprove", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
        // 拼接的不是审核页面，是列表页面 type=1
        String shStr = spellJspStr("1", model); // 拼接查询页面单元格字符串
        ListJspCreate.createListPage(model, shStr, shJsp, "treeTabApprove");

        String shJs = JspUtil.getFilePath(tableName, "treeTabApprove", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createShJs(shJs, model, "treeTabApprove", isHasSubMap, configLst);
    }

    /**
     * TODO 生成公用树模板审核=====针对树模板的审核页面
     *
     * @param model       == 操作的当前模型
     * @param isHasSubMap == 本模型是否含有从表，及从表是否创建表的一些校验
     * @author : xiaoliu
     * @date :2017年6月29日下午3:25:42
     */
    public void createTreeWhJsp(Model model, Map<String, Object> isHasSubMap) {
        //主数据类型==主数据或者字典
        //	String modelType = model.getModelType();
        // 模型实体表名
        String tableName = model.getTableName();
        // 本模型，属性相关设置
        List<AttrConfig> configLst = cacheUtil.getAttrList(model.getId());// 缓存中获取模型的属性信息及配置信息

        String whJsp = JspUtil.getFilePath(tableName, "treeTabWh", JspUtil.spellReJsp(model, "0")); // 根据业务名称加操作类型获取jsp地址
        String whStr = spellJspStr("1", model); // 拼接维护页面单元格字符串，维护页面和查询页面显示的字段相同
        ListJspCreate.createTreeTabListPage(whStr, whJsp, model, "treeTabWh");

        String whJs = JspUtil.getFilePath(tableName, "treeTabWh", JspUtil.spellReJsp(model, "1")); // 拼接js页面内容
        ListJsCreate.createWhJs(whJs, model, "treeTabWh", configLst);

    }
/**===============树模板生成页面方法-----结束 =======================================================*/


    /**
     * 生成多视图的新增页面==动态拼写
     * <p>TODO </p>
     * <p>@param pageType =="2"表示申请页面的新增和编辑   "3"表示变更页面的编辑
     * <p>@param model ==当前操作的模型
     * <p>@param operType "add" 便是申请页面的新增  "edit" 申请页面的编辑  "updateEdit" 便是变更的编辑
     * <p>@param isHasSubMap ==判断是否有从表，及是否（树是否分类树，及分类树的相关操作信息）
     * <p>@return </p>
     *
     * @author : xiaoliu
     * @date :2017年7月8日下午2:08:21
     */
    public String spellTreeAddStr(String pageType, Model model, String operType, Map<String, Object> isHasSubMap) {
        StringBuilder sb = new StringBuilder();
        if (model.getIsMoreView() == 1) {//表示是多视图
            if (pageType.equals("2")) {//说明生成的是申请页面的新增和编辑页面，不含有视图权限
                sb.append(this.spellViewAddStr(pageType, model, operType, isHasSubMap));//生成多视图的新增或编辑页面
            } else if (pageType.equals("3")) {//说明生成的是变更页面的编辑页面，含有视图权限
                //sb.append(this.spellViewUpdateEditStr(model,operType,isHasSubMap)); //生成多视图的变更编辑页面
                sb.append(this.spellViewAddStr(pageType, model, operType, isHasSubMap));//生成多视图的新增或编辑页面
            }
        } else {//表示不是多视图

        }

        return sb.toString();
    }

    /**
     * <p>TODO 生成申请页面的新增或编辑页面</p>
     * <p>@param model ==当前操作模型
     * <p>@param operType "add" 便是申请页面的新增  "edit" 申请页面的编辑
     * <p>@param isHasSubMap ==判断是否有从表，及是否（树是否分类树，及分类树的相关操作信息）
     * <p>@return </p>
     *
     * @author : xiaoliu
     * @date :2017年7月8日下午2:35:29
     */
    public String spellViewAddStr(String pageType, Model model, String operType, Map<String, Object> isHasSubMap) {
        StringBuilder sb = new StringBuilder();
        //首先判断基本视图是否含有属性
        List<AttrConfig> attrLst = this.getAddJspAttrMap(model.getId(), null, pageType);

        if (attrLst.size() > 0) {//说明基本视图里面含有属性
            //1.先拼写基本视图里面的属性
            sb.append(this.spellViewAddBaseRep(model, attrLst, operType));
            //2.在拼写属性组里面的属性
            sb.append(this.spellViewAddGroupRep(model, isHasSubMap, operType, pageType));
        } else { // 基本视图里面不含有属性
            //1.判断属性组里面的属性
            sb.append(this.spellViewAddGroupNoBaseRep(model, isHasSubMap, operType, pageType));
        }

        return sb.toString();
    }

    /**
     * <p>TODO 拼写基本视图里面的属性</p>
     * <p>@param model
     * <p>@param attrLst
     * <p>@param operType
     * <p>@return </p>
     *
     * @author : xiaoliu
     * @date :2017年7月9日上午8:41:11
     */
    public String spellViewAddBaseRep(Model model, List<AttrConfig> attrLst, String operType) {
        //判断是否含有选择设置或编码设置
        List<GenSelectType> typeList = (List<GenSelectType>) this.getSelected(model, operType).get("selLst");
        List<String> columList = (List<String>) this.getSelected(model, operType).get("columList");
        StringBuilder sb = new StringBuilder();

        if (attrLst.size() > 0) {
            sb.append("				<div class='tab-pane fade in active' id='main'> $RN$");
            sb.append("				    <div class=\"wrapper wrapper-content\"> $RN$");
            sb.append("					    <div class=\"row\"> $RN$");
            sb.append("					     	<div class=\"col-sm-5\" style=\"width: 100%; overflow-x: hidden\"> $RN$");
            sb.append("							    <div class=\"ibox float-e-margins\"> $RN$");
            sb.append("								    <div class=\"ibox-title\"> $RN$");
            sb.append("									     <ul class=\"breadcrumb\"> $RN$");
            sb.append("									    	<li><a ng-click=\"backModel()\" class=\"font-green\">" + model.getModelName() + "</a></li> $RN$");
            sb.append("										    <li class=\"active\">基本视图-新增</li> $RN$");
            sb.append("									     </ul> $RN$");
            sb.append("								    </div> $RN$");
            sb.append("								    <div> $RN$");
//	         class=\"ibox-content\"
            for (int i = 0; i < attrLst.size(); i++) {
                AttrConfig attrConfig = attrLst.get(i);
                String ruleId = attrConfig.getRuleTypeId();
                CheckRule checkRule = null;
                if (ruleId != null) {
                    checkRule = checkRuleDao.getById(ruleId);
                }
                //sb.append(AddJspCreate.searchReturnType(typeList, attrConfig, model, operType, checkRule, null));
                sb.append(AddJspCreate.searchViewType(typeList, columList, attrConfig, model, operType, checkRule, null));
            }
            //在此处添加生成按钮
            sb.append(AddJspCreate.spellButtonReplace(model, operType));

            sb.append("	    	                        </div> $RN$");
            sb.append("				               </div> $RN$");
            sb.append("			              </div> $RN$");
            sb.append("		             </div> $RN$");
            sb.append("	            </div> $RN$");
            sb.append("         </div> $RN$");
        }


        return sb.toString().replace("$RN$", "\r\n");
    }

    /**
     * <p>TODO 拼写该模型视图设置的功能</p>
     * <p>@param model
     * <p>@param isHasSubMap
     * <p>@param operType
     * <p>@return </p>
     *
     * @author : xiaoliu
     * @date :2017年7月9日上午8:45:34
     */
    public String spellViewAddGroupRep(Model model, Map<String, Object> isHasSubMap, String operType, String pageType) {
        StringBuilder sb = new StringBuilder();
        //判断是否含有选择设置或编码设置
        List<GenSelectType> typeList = (List<GenSelectType>) this.getSelected(model, operType).get("selLst");
        //获取该模型属性组
        List<AttrGroup> groupLst = (List<AttrGroup>) isHasSubMap.get("benGroupLst");
        List<String> columList = (List<String>) this.getSelected(model, operType).get("columList");
        if (groupLst.size() > 0) {
            for (int i = 0; i < groupLst.size(); i++) {
                AttrGroup attrGroup = groupLst.get(i);
                String groupID = attrGroup.getId();// 获取groupID
                String groupName = attrGroup.getGroupName();
                //获取当前属性组下面的属性
                List<AttrConfig> jspAttrLst = this.getAddJspAttrMap(model.getId(), groupID, pageType);
                sb.append("				<div class='tab-pane fade' id='" + model.getTableName() + "_" + groupID + "_tab'> $RN$");
                sb.append("				    <div class=\"wrapper wrapper-content\"> $RN$");
                sb.append("					    <div class=\"row\"> $RN$");
                sb.append("					     	<div class=\"col-sm-5\" style=\"width: 100%; overflow-x: hidden\"> $RN$");
                sb.append("							    <div class=\"ibox float-e-margins\"> $RN$");
                sb.append("								    <div class=\"ibox-title\"> $RN$");
                sb.append("									     <ul class=\"breadcrumb\"> $RN$");
                sb.append("									    	<li><a ng-click=\"backModel()\" class=\"font-green\">" + model.getModelName() + "</a></li> $RN$");
                sb.append("										    <li class=\"active\">" + groupName + "-新增</li> $RN$ ");
                sb.append("									     </ul> $RN$");
                sb.append("								    </div> $RN$");
                sb.append("								    <div> $RN$");
//		               class=\"ibox-content\"
                for (int j = 0; j < jspAttrLst.size(); j++) {
                    AttrConfig attrConfig = jspAttrLst.get(j);
                    String ruleId = attrConfig.getRuleTypeId();
                    CheckRule checkRule = null;
                    if (ruleId != null) {
                        checkRule = checkRuleDao.getById(ruleId);
                    }
                    // sb.append(AddJspCreate.searchReturnType(typeList, attrConfig, model, operType, checkRule, null));
                    sb.append(AddJspCreate.searchViewType(typeList, columList, attrConfig, model, operType, checkRule, attrGroup));
                }
                //在此处添加生成按钮
                sb.append(AddJspCreate.spellButtonReplace(model, operType));
                sb.append("	    	                        </div> $RN$");
                sb.append("				               </div> $RN$");
                sb.append("			              </div> $RN$");
                sb.append("		             </div> $RN$");
                sb.append("	            </div> $RN$");
                sb.append("         </div> $RN$");
            }
        }

        return sb.toString().replace("$RN$", "\r\n");
    }

    /**
     * <p>TODO 拼写该模型视图设置的功能(没有基本视图)</p>
     * <p>@param model
     * <p>@param isHasSubMap
     * <p>@param operType
     * <p>@return </p>
     *
     * @author : xiaoliu
     * @date :2017年7月9日上午8:45:34
     */
    public String spellViewAddGroupNoBaseRep(Model model, Map<String, Object> isHasSubMap, String operType, String pageType) {
        StringBuilder sb = new StringBuilder();
        //判断是否含有选择设置或编码设置
        List<GenSelectType> typeList = (List<GenSelectType>) this.getSelected(model, operType).get("selLst");
        //获取该模型属性组
        List<AttrGroup> groupLst = (List<AttrGroup>) isHasSubMap.get("benGroupLst");
        List<String> columList = (List<String>) this.getSelected(model, operType).get("columList");
        if (groupLst.size() > 0) {
            //1.找到代表默认属性组（基本视图）
            AttrGroup attrGroup = groupLst.get(0);
            String groupID = attrGroup.getId();// 获取groupID
            String groupName = attrGroup.getGroupName();
            //获取当前属性组下面的属性
            List<AttrConfig> jspAttrLst = this.getAddJspAttrMap(model.getId(), groupID, pageType);
            sb.append("				<div class='tab-pane fade in active ' id='" + model.getTableName() + "_" + groupID + "_tab'> $RN$");
            sb.append("				    <div class=\"wrapper wrapper-content\"> $RN$");
            sb.append("					    <div class=\"row\"> $RN$");
            sb.append("					     	<div class=\"col-sm-5\" style=\"width: 100%; overflow-x: hidden\"> $RN$");
            sb.append("							    <div class=\"ibox float-e-margins\"> $RN$");
            sb.append("								    <div class=\"ibox-title\"> $RN$");
            sb.append("									     <ul class=\"breadcrumb\"> $RN$");
            sb.append("									    	<li><a ng-click=\"backModel()\" class=\"font-green\">" + model.getModelName() + "</a></li> $RN$");
            sb.append("										    <li class=\"active\">" + groupName + "-新增</li> $RN$");
            sb.append("									     </ul> $RN$");
            sb.append("								    </div> $RN$");
            sb.append("								    <div> $RN$");
//	               class=\"ibox-content\"
            for (int j = 0; j < jspAttrLst.size(); j++) {
                AttrConfig attrConfig = jspAttrLst.get(j);
                String ruleId = attrConfig.getRuleTypeId();
                CheckRule checkRule = null;
                if (ruleId != null) {
                    checkRule = checkRuleDao.getById(ruleId);
                }
                // sb.append(AddJspCreate.searchReturnType(typeList, attrConfig, model, operType, checkRule, null));
                sb.append(AddJspCreate.searchViewType(typeList, columList, attrConfig, model, operType, checkRule, attrGroup));
            }
            //在此处添加生成按钮
            sb.append(AddJspCreate.spellButtonReplace(model, operType));
            sb.append("	    	                        </div> $RN$");
            sb.append("				               </div> $RN$");
            sb.append("			              </div> $RN$");
            sb.append("		             </div> $RN$");
            sb.append("	            </div> $RN$");
            sb.append("         </div> $RN$");

            for (int i = 1; i < groupLst.size(); i++) {
                AttrGroup group = groupLst.get(i);
                String gID = group.getId();// 获取groupID
                String gName = group.getGroupName();
                //获取当前属性组下面的属性
                List<AttrConfig> gAttrLst = this.getAddJspAttrMap(model.getId(), gID, pageType);
                sb.append("				<div class='tab-pane fade' id='" + model.getTableName() + "_" + gID + "_tab'> $RN$");
                sb.append("				    <div class=\"wrapper wrapper-content\"> $RN$");
                sb.append("					    <div class=\"row\"> $RN$");
                sb.append("					     	<div class=\"col-sm-5\" style=\"width: 100%; overflow-x: hidden\"> $RN$");
                sb.append("							    <div class=\"ibox float-e-margins\"> $RN$ ");
                sb.append("								    <div class=\"ibox-title\"> $RN$");
                sb.append("									     <ul class=\"breadcrumb\"> $RN$");
                sb.append("									    	<li><a ng-click=\"backModel()\" class=\"font-green\">" + model.getModelName() + "</a></li> $RN$");
                sb.append("										    <li class=\"active\">" + gName + "-新增</li> $RN$");
                sb.append("									     </ul> $RN$");
                sb.append("								    </div> $RN$");
                sb.append("								    <div> $RN$");
//		               class=\"ibox-content\"
                for (int j = 0; j < gAttrLst.size(); j++) {
                    AttrConfig attrConfig = gAttrLst.get(j);
                    String ruleId = attrConfig.getRuleTypeId();
                    CheckRule checkRule = null;
                    if (ruleId != null) {
                        checkRule = checkRuleDao.getById(ruleId);
                    }
                    //sb.append(AddJspCreate.searchReturnType(typeList, attrConfig, model, operType, checkRule, null));
                    sb.append(AddJspCreate.searchViewType(typeList, columList, attrConfig, model, operType, checkRule, group));
                }
                sb.append("	    	                        </div> $RN$");
                sb.append("				               </div> $RN$");
                sb.append("			              </div> $RN$");
                sb.append("		             </div> $RN$");
                sb.append("	            </div> $RN$");
                sb.append("         </div> $RN$");
            }
        }

        return sb.toString().replace("$RN$", "\r\n");
    }

    /**
     * <p>TODO 级联操作的时候，生成的弹出框页面，将会对于清空按钮操作，把级联相关的全部清空</p>
     * <p>@param modelId
     * <p>@param attrId
     * <p>@return </p>
     *
     * @author : xiaoliu
     * @date :2017年11月10日上午10:53:12
     */
    public String spellCascadeAttrStrClear(AttrConfig conf, String caseStr) {
        StringBuilder sb = new StringBuilder();
        //判断当前属性的下一级联操作是否存在，如果存在
        AttrConfig confAttr = cacheUtil.getCascadeAttrConfig(conf.getModelId(), conf.getAttrId());
        if (confAttr != null) {
            String column = confAttr.getAttrColumn();
            sb.append("$(\"#" + column.toLowerCase() + "\").val(\"\"); $RN$");
            sb.append("$(\"#" + column.toLowerCase() + "Name\").val(\"\"); $RN$");
            caseStr = caseStr + sb.toString().replace("$RN$", "\r\n");
            spellCascadeAttrStrClear(confAttr, caseStr);
        }
        //	System.out.println(caseStr);
        return caseStr;
    }

}
